package com.songyang.mqttandothers;

import com.songyang.NotOnlyRedisLock.anno.EnableLock;
import com.songyang.mqttandothers.mqttCore.ClientMQTT;
import com.songyang.mqttandothers.mqttCore.ServerMQTT;
import com.songyang.mqttandothers.service.DeviceService;
import com.songyang.mqttandothers.service.LogService;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;

@EnableLock
@SpringBootApplication
public class MqttAndOthersApplication implements CommandLineRunner {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogService logService;
    private String redisListKey = "mqttList";

    public static void main(String[] args) {
        SpringApplication.run(MqttAndOthersApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        new Thread(() -> {
            while (true) {
                try {
                    String value = blockReadList(999);
                    String[] split = value.split(":");
                    String userId = split[0];
                    String deviceId = split[1];
                    String msg = split[2];
                    String topic = deviceService.getChannel(Integer.valueOf(userId), Integer.valueOf(deviceId));
                    try {
                        new ServerMQTT(topic, msg).start();
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                    insertLog(Integer.valueOf(userId), Integer.valueOf(deviceId), msg);
                } catch (Exception e) {
                }
            }
        }).start();
        new Thread(() -> {
            ClientMQTT client = new ClientMQTT();
            client.start();
//            System.out.println("jieshule");
        }).start();
    }

    public void insertLog(Integer userId, Integer deviceId, String msg) {
        logService.setLog(userId, deviceId, msg);
    }

    public String blockReadList(Integer ThreadBlockTime) throws Exception {
        String result = (String) redisTemplate.execute((RedisCallback<String>) connection -> {
            List<byte[]> bytes = connection.bLPop(ThreadBlockTime, redisListKey.getBytes());
            if (bytes == null || bytes.size() < 1) return null;
            else {
                return new String(bytes.get(bytes.size() - 1));
            }
        });
        if (result == null) return blockReadList(ThreadBlockTime);
        return result;
    }
}